<script setup>
// 热门推荐页 标题和url
import { ref, onMounted, nextTick } from 'vue'
const hotMap = [
  { type: '1', title: '特惠推荐', url: '/hot/preference' },
  { type: '2', title: '爆款推荐', url: '/hot/inVogue' },
  { type: '3', title: '一站买全', url: '/hot/oneStop' },
  { type: '4', title: '新鲜好物', url: '/hot/new' },
]
const query = defineProps({
  type: { type: String, required: true },
})
const hotList = ref({})
const pageParam = ref({ subType: '', pageSize: 10, page: 1 })
const active = ref(0)

// 发起请求获取商品列表方法
const getHotList = async (pageParam) => {
  return (
    await uni.request({
      url: hotMap.find((item) => item.type === query.type).url,
      method: 'GET',
      data: pageParam,
    })
  ).data.result
}

const scrollTop = ref(0)
const oldScrollTop = ref(0)
const lastTapTime = ref(0)

// 监听页面滚动事件
const onScroll = (event) => {
  oldScrollTop.value = event.detail.scrollTop
}
// 双击tab栏返回顶部
const onchangeTabs = async (index) => {
  active.value = index
  // 记录上一次点击的时间
  const currentTime = new Date().getTime()
  if (currentTime - lastTapTime.value < 300) {
    // 如果两次点击间隔小于300毫秒，则执行返回顶部的逻辑
    uni.showLoading({ title: '加载中...', mask: true })
    scrollTop.value = oldScrollTop.value
    getGoodsItems(10, 1, true)
    await nextTick(() => {
      scrollTop.value = 0
    })
  }
  // 更新上一次点击的时间
  lastTapTime.value = currentTime
}

// 刷新商品数据方法
const getGoodsItems = async (pageSize, page, refresh = false) => {
  const currsubType = hotList.value.subTypes[active.value].id
  pageParam.value = {
    subType: currsubType,
    pageSize,
    page,
  }
  console.log(pageParam.value)
  const res = (await getHotList(pageParam.value)).subTypes[active.value].goodsItems.items
  if (refresh) {
    return (hotList.value.subTypes[active.value].goodsItems.items = res)
  }
  hotList.value.subTypes[active.value].goodsItems.items.push(...res)
}

// 页面下拉触底方法
const onScrolltolower = async () => {
  const page = hotList.value.subTypes[active.value].goodsItems.page + 1
  if (page > Math.ceil(counts.value / 10)) {
    uni.showToast({
      title: '没有更多了',
      icon: 'none',
    })
    loadingText.value = '没有更多了...'
    return
  }
  loadingText.value = '正在加载...'
  getGoodsItems(10, page)
}

const counts = ref(0) //商品总数据数量
const loadingText = ref('正在加载...')
onMounted(async () => {
  hotList.value = await getHotList(pageParam.value)
  counts.value = hotList.value.subTypes[active.value].goodsItems.counts
})

// 设置标题
uni.setNavigationBarTitle({ title: hotMap.find((item) => item.type === query.type).title })
</script>

<template>
  <view class="viewport">
    <!-- 推荐封面图 -->
    <view class="cover">
      <image :src="hotList.bannerPicture"></image>
    </view>
    <!-- 推荐选项 -->
    <view class="tabs">
      <text
        class="text"
        :class="active === index ? 'active' : ''"
        v-for="(item, index) in hotList.subTypes"
        @tap="onchangeTabs(index)"
        :key="item"
        >{{ item.title }}</text
      >
    </view>
    <!-- 推荐列表 -->
    <scroll-view
      scroll-y
      class="scroll-view"
      @scrolltolower="onScrolltolower"
      @scroll="onScroll"
      v-for="(item, index) in hotList.subTypes"
      v-show="active === index"
      :key="item"
      :scroll-top="scrollTop"
    >
      <view>
        <view class="goods">
          <navigator
            hover-class="none"
            class="navigator"
            v-for="goods in item.goodsItems.items"
            :key="goods"
            :url="`/pages/goods/goods?id=`"
          >
            <image class="thumb" :src="goods.picture"></image>
            <view class="name ellipsis">{{ goods.name }}</view>
            <view class="price">
              <text class="symbol">¥</text>
              <text class="number">{{ goods.price }}</text>
            </view>
          </navigator>
        </view>
        <view class="loading-text">{{ loadingText }}</view>
      </view>
    </scroll-view>
  </view>
</template>

<style lang="scss" scoped>
page {
  height: 100vh;
  background-color: #f4f4f4;
}
.viewport {
  padding: 180rpx 0 0;
  position: relative;
}
.cover {
  width: 750rpx;
  height: 225rpx;
  border-radius: 0 0 40rpx 40rpx;
  overflow: hidden;
  position: absolute;
  left: 0;
  top: 0;
  image {
    width: 100%;
    height: 100%;
  }
}
.scroll-view {
  height: 75vh;
}
.tabs {
  display: flex;
  justify-content: space-evenly;
  height: 100rpx;
  line-height: 90rpx;
  margin: 0 20rpx;
  font-size: 28rpx;
  border-radius: 10rpx;
  box-shadow: 0 4rpx 5rpx rgba(200, 200, 200, 0.3);
  color: #333;
  background-color: #fff;
  position: relative;
  z-index: 9;
  .text {
    margin: 0 20rpx;
    position: relative;
  }
  .active {
    &::after {
      content: '';
      width: 40rpx;
      height: 4rpx;
      transform: translate(-50%);
      background-color: #27ba9b;
      position: absolute;
      left: 50%;
      bottom: 24rpx;
    }
  }
}
.goods {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  padding: 0 20rpx 20rpx;
  .navigator {
    width: 345rpx;
    padding: 20rpx;
    margin-top: 20rpx;
    border-radius: 10rpx;
    background-color: #fff;
    box-sizing: border-box;
  }
  .thumb {
    width: 305rpx;
    height: 305rpx;
  }
  .name {
    height: 88rpx;
    font-size: 26rpx;
  }
  .price {
    line-height: 1;
    color: #cf4444;
    font-size: 30rpx;
  }
  .symbol {
    font-size: 70%;
  }
  .decimal {
    font-size: 70%;
  }
}

.loading-text {
  text-align: center;
  font-size: 28rpx;
  color: #666;
  padding: 20rpx 0 50rpx;
}
</style>
```
